package com.youzi.tunnel.server.handlers;


import com.youzi.tunnel.common.protocol.Constants;
import com.youzi.tunnel.common.protocol.Message;
import com.youzi.tunnel.server.config.ServerProperties;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import lombok.extern.slf4j.Slf4j;

import java.net.InetSocketAddress;

/**
 * 服务端开启端口处理器
 */
@Slf4j
public class TunnelServerChannelHandler extends SimpleChannelInboundHandler<ByteBuf> {
    private static final boolean isDebugger = ServerProperties.getInstance().isDebugger();

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, ByteBuf buf) throws Exception {
        Channel channel = ctx.channel();
        InetSocketAddress address = (InetSocketAddress) (ctx.channel().remoteAddress());

        //监听端口获取到信息, 尝试获取目标Channel
        Channel toChannel = channel.attr(Constants.TOWARD_CHANNEL).get();

        byte[] data = new byte[buf.readableBytes()];
        buf.readBytes(data);
        if (isDebugger) {
            log.info("服务器[{}:{}]请求转发消息,将转发到目标主机, 数据长度:{} [byte]", address.getHostString(), address.getPort(), data.length);
        }
        //转发信息
        Message message = new Message();
        message.setType(Message.TYPE.RELAY);
        message.setData(data);

        toChannel.writeAndFlush(message);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        Channel channel = ctx.channel();
        InetSocketAddress address = (InetSocketAddress) (ctx.channel().remoteAddress());
        log.error("远程端口主机断开连接[{}:{},channelId={}], message: {}", address.getHostString(), address.getPort(), channel.id(), cause.getMessage());
        Channel towardChannel = channel.attr(Constants.TOWARD_CHANNEL).get();
        towardChannel.close().sync();
        channel.close().sync();
    }
}